<template>
  <div class="role_container">
    <el-card shadow="always" v-loading="roleTableLoading" :body-style="{ padding: '10px' }">
      <el-row :gutter="10">
        <!-- span一行最大24 是一整行的长度 gutter是指定的没干elcol之间的距离 offset是偏移的栏数 -->
        <el-col :span="6" :offset="0">
          <el-input v-model="queryInfo.searchTerm" type="text" size="default" clearable placeholder="请输入角色名" prefix-icon="Search" :input-style="{}" @clear="getRoleTableList">
            <template #append>
              <el-button icon="Search" size="default" @click="getRoleTableList"></el-button>
            </template>
          </el-input>
        </el-col>
        <el-col :span="8" :offset="0">
          <el-button type="primary" icon="Plus" size="default" @click="addRole">添加角色</el-button>
          <el-button type="primary" icon="Delete" size="default" @click="deleteRole">删除角色</el-button>
        </el-col>
      </el-row>
      <el-row :gutter="10">
        <el-col :span="18">
          <el-table :data="roleList" v-loading="roleTableLoading" ref="tableRef" @sort-change="roleSortChanged" @selection-change="handleSelectionChange" size="small" highlight-current-row stripe border style="width: 100%" element-loading-text="Loading..." element-loading-svg-view-box="-10, -10, 50, 50" element-loading-background="rgba(0, 0, 0, 0.8)">
            <!-- label列名  propd对应对象中的key -->
            <el-table-column type="selection" width="55" />
            <el-table-column type="index" :index="computeIndex" width="50" label="序号" />
            <el-table-column prop="roleName" label="角色名" width="150" sortable />
            <el-table-column prop="roleDesc" label="角色描述" width="150" />
            <el-table-column prop="crteTime" label="创建时间" width="150" />
            <el-table-column prop="isActive" label="是否启用" width="100" align="center">
              <template #default="scope">
                <el-switch v-model="scope.row.isActive" @change="changeActiveState(scope.row)" class="ml-2" active-color="#13ce66" inactive-color="#ff4949" />
              </template>
            </el-table-column>
            <el-table-column label="操作">
              <template #default="scope">
                <el-button size="small" icon="Edit" type="primary" @click="showEditDialog(scope.$index, scope.row)">编辑</el-button>
                <el-button size="small" icon="Avatar" type="warning" @click="showAllotRoleDialog(scope.$index, scope.row)">分配角色</el-button>
                <el-button size="small" icon="Delete" type="danger" @click="deleteRoleByIds(scope.$index, scope.row)">删除</el-button>
                <el-button size="small" icon="Setting" type="info" @click="showRolePermission(scope.$index, scope.row)">分配权限</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-col>
        <el-col :span="6">
          <el-row>
            <el-button type="primary" size="small" @click="savePermissions">保存</el-button>
          </el-row>
          <!-- 树形组件  显示数据 node-key 每个树都要有唯一的key id    expand 默认是否展开   
            click-node 是否在点击节点的时候选中节点，默认值为 false，即只有在点击复选框时才会选中节点。 
            check-strictly在显示复选框的情况下，是否严格的遵循父子不互相关联的做法，默认为 false -->
          <el-tree :data="treeData" :default-checked-keys="defaultCheckKeys" :props="defaultProps" ref="treeRef" node-key="id" :check-on-click-node="false" check-strictly show-checkbox default-expand-all />
        </el-col>
      </el-row>
      <el-pagination :currentPage="pageInfo.pageIndex" v-model:page-size="pageInfo.pageSize" :total="pageInfo.totalCount" :page-sizes="[5, 10, 50, 100]" @size-change="handleSizeChange" @current-change="handleCurrentChange" small background layout="total, sizes, prev, pager, next, jumper"> </el-pagination>
    </el-card>
  </div>
  <role-dialog :visible="addDialogVisible" :isCreate="isCreate" :role="roleUpdateInfo" @closeRoleAdd="closeRoleAdd" @refreshRoleList="refreshRoleList"></role-dialog>
  <allot-role-user :visible="allotRoleUserVisible" :roleInfo="roleInfo" :userList="userList" @closeRoleDialog="closeRoleDialog"></allot-role-user>
</template>
<script>
export default {
  name: "Role",
};
</script>
<script setup>
import { getCurrentInstance, ref, reactive, onMounted, onUnmounted } from "vue";
import { useStore } from "vuex";
import { useRouter } from "vue-router";
import { messageUtils } from "assets/js/messageUtils.js";
import { getRolePageList, patchRole, deleteRoles, getRoleInfo, getRoleUserList, getPermissionsByRoleId, setRolePermissions } from "network/role.js";
import { getMenus } from "network/permissions";
import { PaginationData } from "@/model/dataModel.js";
import RoleDialog from "./RoleDialog";
import AllotRoleUser from "./AllotRoleUser";

const { proxy } = getCurrentInstance();
const router = useRouter();
const store = useStore();

let roleTableLoading = ref(false);
//这边指示动态绑定了对象  还是要等组件挂载好了才能获取tableRef的值
//所以要再mounted中使用
const tableRef = ref(null);
//角色列表
let roleList = ref([]);
//查询信息
let queryInfo = reactive({
  searchTerm: "",
  pageIndex: 1,
  pageSize: 10,
});
//分页信息
let pageInfo = reactive(new PaginationData(1, 5, 0));
//选中行数据
let selectedRows = ref([]);
//添加角色的对话框
let addDialogVisible = ref(false);
//分配角色角色的对话框
let allotRoleUserVisible = ref(false);
let isCreate = ref(false);
let roleUpdateInfo = ref({});
let roleInfo = ref({});
let userList = ref([]);
const defaultProps = {
  children: "children",
  label: "authName",
};
let defaultCheckKeys = ref([]);
let treeData = ref([]);
const treeRef = ref(null);
let roleId = ref(null);
const getRoleTableList = async () => {
  roleTableLoading.value = true;
  const res = await getRolePageList(queryInfo);
  if (!res.success) return proxy.$notify.error({ message: res.msg, showClose: true });
  proxy.$notify.success({ message: res.msg, showClose: true });
  roleList.value = res.response;
  roleTableLoading.value = false;
  pageInfo.pageIndex = res.pageIndex;
  pageInfo.pageSize = res.pageSize;
  pageInfo.totalCount = res.totalCount;
};
const getMenuDate = async () => {
  const res = await getMenus("tree");
  if (res.success && res.response) {
    treeData.value = res.response;
  } else {
    messageUtils.messageError(msg);
  }
};

onMounted(() => {
  getRoleTableList();
  getMenuDate();
});
//分页条pageSize变化时
const handleSizeChange = (newSize) => {
  queryInfo.pageSize = newSize;
  getRoleTableList();
};
//分页条pageIndex变化时
const handleCurrentChange = (newIndex) => {
  queryInfo.pageIndex = newIndex;
  getRoleTableList();
};
//更改角色活跃状态
const changeActiveState = async (row) => {
  let patchDocument = reactive([{ op: "add", path: "/isActive", value: row.isActive }]);
  const res = await patchRole(row.id, patchDocument);
  if (!res.success) {
    proxy.$notify.error({ message: res.msg, showClose: true });
    row.isActive = !role.isActive;
  }
  proxy.$notify.success({ message: res.msg, showClose: true });
};

const computeIndex = (index) => {
  return (pageInfo.pageIndex - 1) * pageInfo.pageSize + index + 1;
};
//给表格排序
const roleSortChanged = (column, prop, order) => {
  console.log(column, prop, order);
};
//选中行改变时触发
const handleSelectionChange = (selection) => {
  selectedRows.value = selection;
};
//删除角色
const deleteRole = async () => {
  if (selectedRows.value.length <= 0) return proxy.$notify.error({ message: "请选择要删除的数据", showClose: true });

  let selectedIds = selectedRows.value.map((c) => c.id);
  messageUtils.ElMessageBoxDeleteTips(deleteRoles, getRoleTableList, proxy, selectedIds);
};
//根据id删除角色
const deleteRoleByIds = (index, row) => {
  let id = [];
  id.push(row.id);
  messageUtils.ElMessageBoxDeleteTips(deleteRoles, getRoleTableList, proxy, id);
};
//添加角色
const addRole = () => {
  isCreate.value = true;
  addDialogVisible.value = true;
};
//关闭添加角色的对话框
const closeRoleAdd = () => {
  addDialogVisible.value = false;
  roleUpdateInfo.value = ref({});
};
//添加完成,刷新列表
const refreshRoleList = () => {
  getRoleTableList();
};
//编辑角色
const showEditDialog = async (index, row) => {
  const res = await getRoleInfo(row.id);
  if (!res.success) return proxy.$notify.error({ message: res.msg, showClose: true });
  roleUpdateInfo.value = res.response;
  isCreate.value = false;
  addDialogVisible.value = true;
};
//展示分配角色角色的对话框
const showAllotRoleDialog = async (index, row) => {
  const res = await getRoleUserList(row.id);
  if (!res.success) return proxy.$notify.error({ message: res.msg, showClose: true });
  roleInfo.value = row;

  userList.value = res.response;
  allotRoleUserVisible.value = true;
};
//关闭分配角色的对话框
const closeRoleDialog = () => {
  allotRoleUserVisible.value = false;
};
//展示用户绑定的权限
const showRolePermission = async (index, row) => {
  roleId.value = row.id;
  const res = await getPermissionsByRoleId(row.id);
  if (!res.success) {
    proxy.$notify.error({ message: res.msg, showClose: true });
    defaultCheckKeys.value = ref([]);
    treeRef.value.setCheckedKeys([]);
  } else {
    treeRef.value.setCheckedKeys([]);
    defaultCheckKeys.value = res.response;
  }
};

//保存用户绑定的权限
const savePermissions = async () => {
  //通过设置check-strictly=true,可获取全部选中节点数据
  if (roleId.value) {
    const selectedIds = treeRef.value
      .getCheckedNodes()
      .map((c) => c.id)
      .join(",");

    // const fullCheckedId = treeRef.value.getCheckedNodes().map((c) => c.id);
    // //设置check-strictly=false,可获得选中半节点的数据，但是重新加载后，父级半节点会导致子级节点全部选中
    // const halfCheckedId = treeRef.value.getHalfCheckedNodes().map((c) => c.id);
    // fullCheckedId.push(halfCheckedId);
    // const selectedIds = fullCheckedId.join(",");
    const res = await setRolePermissions(roleId.value, selectedIds);
    if (res.success) return proxy.$notify.success({ message: res.msg, showClose: true });
    return proxy.$notify.error({ message: res.msg, showClose: true });
  }
};
</script>
<style lang="less" scoped></style>
